function EditorViewer(edDoc) {
    this.m_edDoc = edDoc; //Editor Doc;
    this.m_visiblePages = [];//visible pageview; 
    this.m_lsPageView = [];//pageview list
    this.m_nScale = 1;
    this.m_nPT2PX = 96 / 72;
    this.m_nPageSpace = 10; //space between 2 page;
    this.m_nMarginTop = 10; //margin between viewer and first page;
    this.m_nMarginLeft = 10;
    this.m_nMarginRight = 10;
    this.m_nViewerX = 0; //the left of viewer;
    this.m_nViewerY = 0; //the top of viewer;
    this.m_areaDiv = null; //the div element for instand of the area of viewr
    this.m_nStartPageIndex = -1;
    this.m_rotateFactor = 0; //0:0�ȣ�1��90�ȣ�2��180�ȣ�3��270��
    //this.m_StartCaretInfo = new CARET_INFO();
    this.m_pSLArray = [];
    this.m_fontLoader =null;

    this.GetAreaDiv = function () { return this.m_areaDiv; };

    this.InitViewer = function (domDoc, xPos, yPos, divArea) {
        if (this.m_edDoc == null) return false;
        this.CreateViewArea(xPos, yPos, divArea);
        this.BuildViewList();
        this.CalcLayout();
        this.m_fontLoader = new FontLoader(this.m_edDoc.pdDoc);
        this.m_fontLoader.standFont = FXREADER.Config.FontUrl.StandFontUrl;
        this.m_fontLoader.webFont = FXREADER.Config.FontUrl.WebFontUrl;
        var vs = this.GetPageViewCount();
        for (var i = 0; i < vs; i++) {
            var v = this.GetPageView(i);
            if (null != v) {
                v.CreateCanvas();
            }
        }
        return true;
    };
    this.BuildViewList = function(){
        var nPages = this.m_edDoc.GetEditorPageCount();
        for (var i = 0; i < nPages; i++) {
            var edPage = this.m_edDoc.GetEditorPage(i);
            var pageView = new EditorPageView();
            pageView.SetEDPage(edPage);
            pageView.SetViewer(this);
            pageView.SetPageIndex(i);
            this.m_lsPageView[i] = pageView;
        }
    };
    this.GetPageViewCount = function(){return this.m_lsPageView.length;};
    this.GetPageView = function(iPage){
        if(iPage<0||iPage>=this.GetPageViewCount())
            return null;
        return this.m_lsPageView[iPage];
    };

    //Create a div element for instand of the area of viewer
    this.CreateViewArea = function (xPos, yPos, parentDiv) {
        var theDiv = document.createElement("div");
        theDiv.style.display = "inline";
        theDiv.style.padding = "0";
        theDiv.setAttribute("id", "ViewerArea");
        theDiv.style.position = "absolute";
        theDiv.style.margin = "0px auto 0px" ;
        //theDiv.style.zIndex = 0;
        theDiv.style.left = 0;//xPos;
        theDiv.style.top = 0;//yPos;
        theDiv.style.right = 0;
        theDiv.style.bottom = 0;
        theDiv.style.overflow = "auto";
        this.m_areaDiv = theDiv;
        parentDiv.appendChild(theDiv); 
        //添加滚动条
    };

    //Calculate the page layout info,such as the position of the page
    this.CalcLayout = function () {
        //  var nCurStartY = m_nMarginTop;
        // var nCurStartX = m_nMarginLeft;
        var nTotalPageHeight = 0;
        var nMaxWidth = 0;
        var nPages = this.m_edDoc.GetEditorPageCount();
        for (var i = 0; i < nPages; i++) {
            var edPage = this.m_edDoc.GetEditorPage(i);
            if (null == edPage) continue;
            var pageView = this.GetPageView(i);
            if (null == pageView) continue;
            var width = parseInt(edPage.GetPageWidth() * this.m_nPT2PX * this.m_nScale + 0.5);
            var height = parseInt(edPage.GetPageHeight() * this.m_nPT2PX * this.m_nScale + 0.5);
            if (1 == this.m_rotateFactor || 3 == this.m_rotateFactor) {
                var temp = height;
                height = width;
                width = temp;
            }
			pageView.m_width = width;
			pageView.m_height = height;
			pageView.m_curRotateState = this.m_rotateFactor;
        }

    };
    
    this.SetZoomFactor = function (zoomFactor) {
    	var curPosArr = this.GetCurViewPosition();
        this.m_nScale = zoomFactor;
        this.UpdateAllPageViewSize();
        var totalHeight = 0;
        for (var i = 0, index = curPosArr[0]; i < index; i++) {
        	totalHeight += this.m_nPageSpace;
        	totalHeight += this.GetPageView(i).m_height;
        }
        totalHeight += curPosArr[2];
        if (0 !== curPosArr[1]) {
        	totalHeight += this.GetPageView(i).m_height * curPosArr[1];
        }
        document.getElementById("ViewerArea").scrollTop = totalHeight;
    };
    this.GetZoomFactor = function () {
        return this.m_nScale;
    };
    this.SetRotateFactor = function (rotateFactor) {
    	var curPosArr = this.GetCurViewPosition();
    	
        this.m_rotateFactor = rotateFactor;
        this.UpdateAllPageViewSize();
        
        var totalHeight = 0;
        for (var i = 0, index = curPosArr[0]; i < index; i++) {
        	totalHeight += this.m_nPageSpace;
        	totalHeight += this.GetPageView(i).m_height;
        }
        totalHeight += curPosArr[2];
        if (0 !== curPosArr[1]) {
        	totalHeight += this.GetPageView(i).m_height * curPosArr[1];
        }
        document.getElementById("ViewerArea").scrollTop = totalHeight;
    };
    this.GetRotateFactor = function () {
        return this.m_rotateFactor;
    };
    this.DrawPages = function (bForce) {
        this.EnumVisblePages();
        //var tempDataMgr = DataMgr.prototype.GetDataMgr();
        //var tempDataMgr = new DataMgr();
        var tempDocId = this.m_edDoc.pdDoc.docId;
        for (var i = 0, pageSum = this.CountVisiblePage(); i < pageSum; i++) {
        	if (!bForce) {
        		if (this.m_visiblePages[i] === null) continue;
        		if (!this.m_visiblePages[i].bFresh) continue;
        	}
            var v = this.GetVisiblePage(i);
            if (v == null) continue;
            if (v.m_edPage == null) continue;
            if (v.m_edPage.pdPage == null) {
            	if (v.m_dataMgr == null) {
	            	var tempDataMgr = new DataMgr(this.m_edDoc.pdDoc);
	            	v.m_dataMgr = tempDataMgr;
	            	this.m_fontLoader.callback = v.Display;
            		this.m_fontLoader.caller = v;
            		this.m_fontLoader.pageIndex = v.m_nPageIndex;
            		tempDataMgr.DownloadData(tempDocId, v.m_nPageIndex, this.m_fontLoader.LoadFamiliesByPage,  this.m_fontLoader);
	            	//tempDataMgr.DownloadData(tempDocId, v.m_nPageIndex, EditorPageView.prototype.Display, v);
            	}
            }
            else{
            	if (v.m_edPage.pdPage.bFinishParseJson
            		&&(v.m_edPage.pdPage.bFinishLoadImgs || v.m_edPage.pdPage.imgObjCount === 0)) {
            		this.m_fontLoader.callback = v.Display;
            		this.m_fontLoader.caller = v;
            		this.m_fontLoader.pageIndex = v.m_nPageIndex;
            		this.m_fontLoader.LoadFamiliesByPage();
            		//v.Display();
            	}
            }
        }
    };
    this.EnumVisblePages = function () {
        var viewerDiv = document.getElementById("ViewerArea");
    	var scrollTop = viewerDiv.scrollTop;
    	var pageCount = this.GetPageViewCount();
    	var pageView, pageHeight;
    	var nTotalHeight = 0;
    	var oldVisiblePages = this.m_visiblePages;
    	var visibleObj = null;
    	this.m_visiblePages = []; // visible obj
    	for (var i = 0; i < pageCount; i++) {
    		nTotalHeight += this.m_nPageSpace / 2;
    		pageView = this.GetPageView(i);
    		pageHeight = pageView.m_height;
    		if ((nTotalHeight > scrollTop && nTotalHeight < scrollTop + viewerDiv.offsetHeight)
    			||(nTotalHeight < scrollTop && nTotalHeight + pageHeight > scrollTop)) {
    			visibleObj = new Object();
    			visibleObj.bFresh = true;
    			visibleObj.pageView = pageView;
    			this.m_visiblePages.push(visibleObj);
    		}
    		nTotalHeight += pageHeight;
    		nTotalHeight += this.m_nPageSpace / 2;
    		if (nTotalHeight > (scrollTop + viewerDiv.offsetHeight)) {
    			break;
    		}
    	}
    	// handle new visible pages
    	var curIndex = 0;
    	for (var j = 0, len = this.m_visiblePages.length; j < len; j++) {
    		pageView = this.m_visiblePages[j].pageView;
    		curIndex = pageView.m_nPageIndex;
    		for (var k = 0, oldLen = oldVisiblePages.length; k < oldLen; k++) {
    			if (curIndex == oldVisiblePages[k].pageView.m_nPageIndex) {
    				this.m_visiblePages[j].bFresh = false;
    			}
    		}
    	}
    };
    this.CountVisiblePage = function () { return this.m_visiblePages.length; };
    this.GetRotation = function () { return this.m_nRotate; };
    this.GetVisiblePage = function (i) {
    	 if (null === this.m_visiblePages[i]) return null;
    	 return this.m_visiblePages[i].pageView; 
   	};

	this.GotoNextPage = function() {
		if (this.m_visiblePages.length <= 0) return;
		var firstVisiblePageViewIndex = this.m_visiblePages[0].pageView;
		var viewerarea = document.getElementById("ViewerArea");
		var scrollTo = 0;
		var destIndex = firstVisiblePageViewIndex.m_nPageIndex + 1;
		if (destIndex >= this.GetPageViewCount()) return;
		for (var i = 0; i < destIndex; i++) {
			scrollTo += this.m_nPageSpace;
			scrollTo += this.GetPageView(i).m_height;
		}
		viewerarea.scrollTop = scrollTo;
	};
	this.GotoPreviousPage = function() {
		if (this.m_visiblePages.length <= 0) return;
		var firstVisiblePageViewIndex = this.m_visiblePages[0].pageView;
		var viewerarea = document.getElementById("ViewerArea");
		var scrollTo = 0;
		var destIndex = firstVisiblePageViewIndex.m_nPageIndex - 1;
		if (destIndex < 0) return;
		for (var i = 0; i  < destIndex; i++) {
			scrollTo += this.m_nPageSpace;
			scrollTo += this.GetPageView(i).m_height;
		}
		viewerarea.scrollTop = scrollTo;
	};
	this.GotoFirstPage = function() {
		this.GotoPage(0);
	};
	this.GotoLastPage = function() {
		this.GotoPage(this.GetPageViewCount() - 1);
	};

    this.GotoPage = function (index) {
        if (index < 0 || index >= this.GetPageViewCount()) return;
		var viewerarea = document.getElementById("ViewerArea");
		if (0 === index) {
			viewerarea.scrollTop = 0;
			return;
		}
		var scrollTo = 0;//this.m_nPageSpace;
		var pageView = null;
		for (var i = 0; i < index; i++) {
			scrollTo += this.GetPageView(i).m_height;
			scrollTo += this.m_nPageSpace;
		}
		viewerarea.scrollTop = scrollTo;
    };
    
    
    this.UpdateAllPageViewSize = function() {
    	var pvCount = this.GetPageViewCount();
    	var pv = null;
        for (var i = 0; i < pvCount; i++) {
            pv = this.GetPageView(i);
            if (null != pv) {
                pv.AdjustPageViewSize();
            }
        }
    };
    
    // return value: [iPage, percent-in-page, position-in-pageSpace]
    this.GetCurViewPosition = function() {
    	var viewerDiv = document.getElementById("ViewerArea");
    	var vScrollPos = viewerDiv.scrollTop;
    	var pageCount = this.GetPageViewCount();
    	var totalHeight = 0;
    	var pageView;
    	var curPageIndex = 0;
    	var pagePosPercent = 0;
    	var posInPageSpace = 0;
    	for (var i = 0; i < pageCount; i++) {
    		totalHeight += this.m_nPageSpace;
    		pageView = this.GetPageView(i);
    		totalHeight += pageView.m_height;
    		if (totalHeight >= vScrollPos) {
    			curPageIndex = i;
    			break;
    		}
    	}
    	var pageTop = totalHeight - pageView.m_height;
    	var lastPageBottom = pageTop - this.m_nPageSpace;
    	if (vScrollPos >= lastPageBottom && vScrollPos <= pageTop) {
    		posInPageSpace = vScrollPos - lastPageBottom;
    		return [curPageIndex, pagePosPercent, posInPageSpace];
    	}
    	else if (vScrollPos > pageTop) {
    		pagePosPercent = (vScrollPos - pageTop) / pageView.m_height;
    		return [curPageIndex, pagePosPercent, this.m_nPageSpace];
    	}
    };
    
    this.TextOnMouseDown = function(mousePS,pageIndex){
    	if (this.m_lsPageView.length <= 0 || pageIndex == null) return;
    	this.ClearSelection();
    	this.m_nStartPageIndex = pageIndex;
		var SelectVisiblePageView= this.m_lsPageView[pageIndex];
		SelectVisiblePageView.GetTextInfo(mousePS,this.m_StartCaretInfo);
		//console.log(this.m_StartCaretInfo);
    };
    
    this.InitTextPage = function(){
    	if (this.m_lsPageView.length <= 0) return;
    	for(var i = 0; i < this.m_lsPageView.length;i++){
    		var visiblePageView = this.m_lsPageView[i];
    		visiblePageView.InitTextpage();
    	}
    };
    this.TextOnMouseMove = function(mousePS,pageIndex){
    	if (this.m_lsPageView.length <= 0 || pageIndex == null || this.m_StartCaretInfo.index == -1) return;
    	var SelectVisiblePageView= this.m_lsPageView[pageIndex];
    	var CurCaretInfo = new CARET_INFO();
		SelectVisiblePageView.GetTextInfo(mousePS,CurCaretInfo);
		//console.log(CurCaretInfo);
		if(this.CalcSelect(this.m_StartCaretInfo,CurCaretInfo,this.m_nStartPageIndex,pageIndex)){
			this.HighLightRects();
		}
    };
    this.ClearSelection = function () {
        var nCount = this.m_pSLArray.length;
        for (var i = 0; i < nCount; i++) {
            var index = this.m_pSLArray[i];
            var pSLPage = this.m_lsPageView[index];
            if (pSLPage) {
                pSLPage.ClearSelectRect();
            }
        }
    };
    this.CalcSelect = function(caret1, caret2, iPage1, iPage2){
    	if (iPage1 < 0 || iPage2 < 0 || caret1.index == -1 || caret2.index == -1)
                return false;
    	//console.log("page1:"+iPage1+"page2:"+iPage2);
    	
    	var select_array = [];
        select_array = this.m_pSLArray;
        this.m_pSLArray.length = 0;
        var count = select_array.length;
        for (var i = 0; i < count; i++) {
            if (iPage1 > iPage2) {
                if (select_array[i] > iPage1 || select_array[i] < iPage2) {
                    var pPage = this.m_lsPageView[select_array[i]];
                    if (!pPage)
                        return false;
                    pPage.ClearSelectRect();
                    this.m_pSLArray.push(select_array[i]);
                }
            }
            else {
                if (select_array[i] > iPage2 || select_array[i] < iPage1) {
                    var pPage = this.m_lsPageView[select_array[i]];
                    if (!pPage)
                        return false;
                    pPage.ClearSelectRect();
                    this.m_pSLArray.push(select_array[i]);
                }
            }
        }
    	if (iPage1 < iPage2) {
    		 var pPage1 = this.m_lsPageView[iPage1];
             var pPage2 = this.m_lsPageView[iPage2];
             if (!pPage1 || !pPage2)
                 return false;
            pPage1.AddSLRectByIndex(caret1.bLeft == false ? caret1.index + 1 : caret1.index,pPage1.GetTXTPage().GetSize()-1, caret1.textIndex,pPage1.GetEDPage().pdPage.textObjCount - 1);
            this.m_pSLArray.push(iPage1);
	        for (var i = iPage1 + 1; i < iPage2; i++) {
		        var pPage = this.m_lsPageView[i];
		        if (!pPage)
		            return false;
		        pPage.SelectAll();
		        if (pPage.IsSelected()) {
		            this.m_pSLArray.push(i);
		        }
		    }
          pPage2.AddSLRectByIndex(0, caret2.bLeft ? caret2.index - 1 : caret2.index,0,caret2.textIndex);
          this.m_pSLArray.push(iPage2);

	      if (this.m_pSLArray.length == 0) {
	            return false;
	      }
	      return true;
    	}
    	if (iPage1 > iPage2) {
            var pPage1 = this.m_lsPageView[iPage1];
            var pPage2 = this.m_lsPageView[iPage2];
            if (!pPage1 || !pPage2)
                return false;
            pPage2.AddSLRectByIndex(caret2.bLeft == false ? caret2.index + 1 : caret2.index,caret1.index,pPage2.GetTXTPage().GetSize()-1, caret2.textIndex,pPage2.GetEDPage().pdPage.textObjCount - 1);
            this.m_pSLArray.push(iPage2);

            for (var i = iPage2 + 1; i < iPage1; i++) {
                var pPage = this.m_lsPageView[i];
                if (!pPage)
                    return false;
                pPage.SelectAll();
                if (pPage.IsSelected()) {
                    this.m_pSLArray.push(i);
                }
            }

            pPage1.AddSLRectByIndex(0, caret1.bLeft ? caret1.index - 1 : caret1.index, caret1.textIndex,pPage1.GetEDPage().pdPage.textObjCount - 1);
            this.m_pSLArray.push(iPage1);

            if (this.m_pSLArray.length == 0) {
                return false;
            }
            return true;
        }
    	
    	var index1 = caret1.index;
        var index2 = caret2.index;
        //console.log("index1:"+index1+"index2:"+index2);
        if (caret1.textIndex < caret2.textIndex) {
            if (caret1.bLeft == false) {
                index1++;
            }
            if (caret2.bLeft == true) {
                index2--;
            }
            var pPage = this.m_lsPageView[iPage1];
            if (!pPage)
                return false;
            pPage.AddSLRectByIndex(index1, index2, caret1.textIndex,caret2.textIndex);
            this.m_pSLArray.push(iPage1);
            return true;
        }
        if (caret1.textIndex > caret2.textIndex) {
            if (caret2.bLeft == false) {
                index2++;
            }
            if (caret1.bLeft == true) {
                index1--;
            }
            var pPage = this.m_lsPageView[iPage1];
            if (!pPage)
                return false;
            pPage.AddSLRectByIndex(index2, index1,caret2.textIndex,caret1.textIndex);
            this.m_pSLArray.push(iPage1);
            return true;
        }
        if (caret1.textIndex == caret2.textIndex) {
        	console.log(caret1);
        	console.log(caret2);
        	if(caret1.index == caret2.index && caret1.bLeft == true)index1--;
        	else{
	        	 if (caret1.bLeft == false) {
	                index1++;
	            }
	        	 
	            if (caret2.bLeft == true) {
	                index2--;
	            }
            }
            var pPage = this.m_lsPageView[iPage1];
            if (!pPage)
                return false;
            pPage.AddSLRectByIndex(index1, index2, caret1.textIndex,caret2.textIndex);
            this.m_pSLArray.push(iPage1);
            return true;
        }
       
        return false;
    };
    
    this.HighLightRects = function () {
        var nCount = this.m_pSLArray.length;
        for (var i = 0; i < nCount; i++) {
            var index = this.m_pSLArray[i];
            var pSLPage = this.m_lsPageView[index];
            if (!pSLPage) {
                continue;
            }
            var rect_array = [];
            pSLPage.GetSelectPDFRect(rect_array);
            //console.log(rect_array);
            pSLPage.InitHighLightsDiv(rect_array);
        }
    };
    
    this.TextOnMouseUp = function(mousePS,pageIndex){
    	if (this.m_lsPageView.length <= 0 || pageIndex == null) return;
    	this.m_StartCaretInfo = new CARET_INFO();
    	var SelectVisiblePageView= this.m_lsPageView[pageIndex];
		//SelectVisiblePageView.EndSelectChar(mousePS[0],mousePS[1]);
    };
    this.UpdateSelectText = function(){
    	this.HighLightRects();
    	
    };
    
    this.RotateSelectText = function(){
    	var nCount = this.m_pSLArray.length;
    	
    	switch(this.m_rotateFactor){
    	case 1:
    		for(var i = 0; i < nCount; i++){
    			var index = this.m_pSLArray[i];
    			var pSLPage = this.m_lsPageView[index];
    			if(!pSLPage){
    				continue;
    			}
    			var rect_array = [];
    			pSLPage.Rotate90HighLigths(rect_array);
    			pSLPage.InitHighLightsDiv(rect_array);
    		}
    		break;
    	case 2:break;
    	case 3:break;
    	}
    };
}